import 'dart:convert';
import 'package:audioplayers/audio_cache.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:qgchat/http/models/VideoInvitationModel.dart';
import 'package:qgchat/common/global/global.dart';
import 'package:qgchat/widgets/notice/notice.dart';
import 'package:qgchat/widgets/tipsDialog.dart';

class SocketBuilder extends StatefulWidget {
  final Widget child;

  SocketBuilder({@required this.child, Key key}) : super(key: key);

  @override
  _SocketBuilderState createState() => _SocketBuilderState();
}

class _SocketBuilderState extends State<SocketBuilder> {
  AudioCache audio = AudioCache();

  @override
  void initState() {
    super.initState();

    audio.loadAll(["audio/online.mp3"]);

    final not = Global.socketNot;
    not.addListener(() {
      if (not.value == null) return;

      // 有用户上线监听
      not.value
          .map((str) => jsonDecode(str))
          .where((cls) => cls['datatype'] == 'userlogin')
          .listen(
        (res) {
          audio.play("audio/online.mp3");
        },
      );

      // 充值广播
      not.value
          .map((str) => jsonDecode(str))
          .where((cls) => cls['datatype'] == 'allmoney')
          .map((map) => NoticeRechargeModel.fromJson(map['data']))
          .listen(
        (res) {
          GlobalNotice().push(
            NoticeModel(
              name: "${res.name ?? '神秘人'}",
              gold: res.money ?? 0,
            ),
          );
        },
      );

      // 通话邀请
      not.value
          .map((str) => jsonDecode(str))
          .where((cls) => cls['datatype'] == 'invitation')
          .map((map) => VideoInvitationModel.fromJson(map['data']))
          .listen(
        (res) async {
          Logger().i(res);
          final context = Global.noCtxRoute.navigatorKey.currentContext;

          // 正在通话时拦截邀请
          if (Global.talking.value) return;

          // 权限判断
          final pmsArr = await PermissionHandler().requestPermissions([
            PermissionGroup.camera,
            PermissionGroup.microphone,
          ]);
          final granted = PermissionStatus.granted;
          final camera = pmsArr[PermissionGroup.camera] == granted;
          final microphone = pmsArr[PermissionGroup.microphone] == granted;
          if (!camera || !microphone) {
            showDialog(
              context: context,
              builder: (BuildContext context) {
                return dialogBuild(
                  context,
                  title: "需要你的授权",
                  msg: ["必须授予摄像头和麦克风权限才能视频"],
                  confirmText: '去授权',
                  confirmFn: () {
                    PermissionHandler().openAppSettings();
                  },
                );
              },
            );
            return;
          }

          // 跳转到等待接听页面
          goPage(
            context,
            '/makeCall',
            param: {
              "token": res.token,
              "inv": res.inv,
            },
          );
        },
      );
    });
  }

  // 监听有新用户上线
  socketNot() {
    if (Global.socketNot.value == null) return;
    final not = Global.socketNot;

    Global.socketNot.value
        .map((str) => jsonDecode(str))
        .where((cls) => cls['datatype'] == 'userlogin')
        .listen(
      (res) {
        audio.play("audio/online.mp3");
      },
    );

    not.addListener(() {
      if (not.value == null) return;
      not.value
          .map((str) => jsonDecode(str))
          .where((cls) => cls['datatype'] == 'allmoney')
          .map((map) => NoticeRechargeModel.fromJson(map['data']))
          .listen(
        (res) {
          GlobalNotice().push(
            NoticeModel(
              name: "${res.name ?? '神秘人'}",
              gold: res.money ?? 0,
            ),
          );
        },
      );
    });
  }

  @override
  Widget build(BuildContext context) => widget.child;
}

class NoticeRechargeModel {
  String name;
  int money;
  String head;

  NoticeRechargeModel({this.name, this.money, this.head});

  NoticeRechargeModel.fromJson(Map<String, dynamic> json) {
    name = json['name'];
    money = json['money'];
    head = json['head'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['name'] = this.name;
    data['money'] = this.money;
    data['head'] = this.head;
    return data;
  }
}
